home *** CD-ROM | disk | FTP | other *** search
/ Gigantic Games 2 / Gigantic Games 2.iso / pc / _z_ / zorkmachine / sound.c < prev    next >
C/C++ Source or Header  |  1994-12-23  |  9KB  |  383 lines

  1. #include <graphics/gfxbase.h>
  2. #include <devices/audio.h>
  3. #include <dos/dosextens.h>
  4. #include <dos/dostags.h>
  5. #include <exec/memory.h>
  6.  
  7. #include <clib/exec_protos.h>
  8. #include <clib/dos_protos.h>
  9.  
  10. #include <stdlib.h>
  11. #include <string.h>
  12.  
  13. #define SIG_SOUND    (1 << SoundPort -> mp_SigBit)
  14. #define SIG_AUDIO    (1 << AudioPort -> mp_SigBit)
  15. #define SIG_KILL    SIGBREAKF_CTRL_C
  16. #define SIG_HANDSHAKE    SIGBREAKF_CTRL_D
  17.  
  18. extern struct GfxBase    *GfxBase;
  19. extern struct Process    *ThisProcess;
  20.  
  21. STATIC struct Process    *SoundProcess;
  22. STATIC struct MsgPort    *SoundPort;
  23.  
  24. #ifdef AZTEC_C
  25.  
  26. #define __saveds
  27.  
  28. #endif    /* AZTEC_C */
  29.  
  30. struct SoundHeader
  31. {
  32.     UBYTE    Reserved0[2];
  33.     BYTE    Times;
  34.     UBYTE    Rate[2];    /* Note: little endian */
  35.     UBYTE    Reserved1[3];
  36.     UWORD    PlayLength;
  37. };
  38.  
  39. struct SoundMessage
  40. {
  41.     struct Message    VanillaMsg;
  42.     LONG        ID,
  43.             Volume;
  44. };
  45.  
  46. VOID __saveds
  47. SoundServer()
  48. {
  49. #ifdef AZTEC_C
  50.     geta4();
  51. #endif    /* AZTEC_C */
  52.  
  53.     if(SoundPort = CreateMsgPort())
  54.     {
  55.         struct SoundMessage    *Msg;
  56.         APTR             Data    = NULL;
  57.         ULONG             SignalSet;
  58.         BYTE             Terminated = FALSE;
  59.         struct MsgPort        *AudioPort    = NULL;
  60.         struct IOAudio        *AudioRequest    = NULL,
  61.                     *AudioControl;
  62.         LONG             Volume = -1;
  63.  
  64.         if(AudioControl = (struct IOAudio *)AllocVec(sizeof(struct IOAudio),MEMF_PUBLIC | MEMF_ANY))
  65.         {
  66.             Signal((struct Task *)ThisProcess,SIG_HANDSHAKE);
  67.  
  68.             while(!Terminated)
  69.             {
  70.                 SignalSet = Wait(SIG_SOUND | SIG_KILL);
  71.  
  72.                 if(SignalSet & SIG_KILL)
  73.                 {
  74.                     if(AudioPort)
  75.                     {
  76.                         if(!CheckIO((struct IORequest *)AudioRequest))
  77.                             AbortIO((struct IORequest *)AudioRequest);
  78.  
  79.                         WaitIO((struct IORequest *)AudioRequest);
  80.  
  81.                         CloseDevice((struct IORequest *)AudioRequest);
  82.  
  83.                         DeleteIORequest(AudioRequest);
  84.  
  85.                         DeleteMsgPort(AudioPort);
  86.  
  87.                         FreeVec(Data);
  88.                     }
  89.  
  90.                     break;
  91.                 }
  92.  
  93.                 if(SignalSet & SIG_SOUND)
  94.                 {
  95.                     while(Msg = (struct SoundMessage *)GetMsg(SoundPort))
  96.                     {
  97.                         if(Msg -> Volume != Volume && AudioPort)
  98.                         {
  99.                             if(!Msg -> Volume)
  100.                             {
  101.                                 if(!CheckIO((struct IORequest *)AudioRequest))
  102.                                     AbortIO((struct IORequest *)AudioRequest);
  103.  
  104.                                 WaitIO((struct IORequest *)AudioRequest);
  105.  
  106.                                 CloseDevice((struct IORequest *)AudioRequest);
  107.  
  108.                                 DeleteIORequest(AudioRequest);
  109.  
  110.                                 DeleteMsgPort(AudioPort);
  111.  
  112.                                 FreeVec(Data);
  113.  
  114.                                 AudioRequest    = NULL;
  115.                                 AudioPort    = NULL;
  116.                                 Data        = NULL;
  117.                                 Volume        = 0;
  118.                             }
  119.                             else
  120.                             {
  121.                                 Volume = Msg -> Volume * 8;
  122.  
  123.                                 AudioControl -> ioa_Request . io_Command    = ADCMD_PERVOL;
  124.                                 AudioControl -> ioa_Request . io_Flags        = ADIOF_NOWAIT | ADIOF_PERVOL;
  125.                                 AudioControl -> ioa_Volume            = Volume;
  126.  
  127.                                 BeginIO((struct IORequest *)AudioControl);
  128.                                 WaitIO((struct IORequest *)AudioControl);
  129.                             }
  130.                         }
  131.                         else
  132.                         {
  133.                             if(AudioPort)
  134.                             {
  135.                                 AudioRequest -> ioa_Request . io_Command = ADCMD_FINISH;
  136.  
  137.                                 DoIO((struct IORequest *)AudioRequest);
  138.  
  139.                                 CloseDevice((struct IORequest *)AudioRequest);
  140.  
  141.                                 DeleteIORequest(AudioRequest);
  142.  
  143.                                 DeleteMsgPort(AudioPort);
  144.  
  145.                                 FreeVec(Data);
  146.  
  147.                                 AudioRequest    = NULL;
  148.                                 AudioPort    = NULL;
  149.                                 Data        = NULL;
  150.                             }
  151.  
  152.                             if(Msg -> ID)
  153.                             {
  154.                                 struct SoundHeader    Header;
  155.                                 BPTR            File;
  156.                                 UBYTE            Buffer[100];
  157.  
  158.                                 sprintf(Buffer,"Sound/s%ld.dat",Msg -> ID);
  159.  
  160.                                 if(File = Open(Buffer,MODE_OLDFILE))
  161.                                 {
  162.                                     if(Read(File,&Header,sizeof(Header)) == sizeof(Header))
  163.                                     {
  164.                                         if(Data = AllocVec(Header . PlayLength,MEMF_CHIP))
  165.                                         {
  166.                                             if(Read(File,Data,Header . PlayLength) == Header . PlayLength)
  167.                                             {
  168.                                                 if(AudioPort = CreateMsgPort())
  169.                                                 {
  170.                                                     if(AudioRequest = (struct IOAudio *)CreateIORequest(AudioPort,sizeof(struct IOAudio)))
  171.                                                     {
  172.                                                         STATIC UBYTE Allocation[4] = { 1,2,4,8 };
  173.  
  174.                                                         AudioRequest -> ioa_Request . io_Message . mn_Node . ln_Pri    = 127;
  175.                                                         AudioRequest -> ioa_Request . io_Command            = ADCMD_ALLOCATE;
  176.                                                         AudioRequest -> ioa_Request . io_Flags                = ADIOF_NOWAIT | ADIOF_PERVOL;
  177.                                                         AudioRequest -> ioa_Data                    = Allocation;
  178.                                                         AudioRequest -> ioa_Length                    = 4;
  179.  
  180.                                                         if(!OpenDevice(AUDIONAME,0,(struct IORequest *)AudioRequest,0))
  181.                                                         {
  182.                                                             ULONG Rate = (Header . Rate[1] << 8) | Header . Rate[0];
  183.  
  184.                                                             Volume = Msg -> Volume * 8;
  185.  
  186.                                                             AudioRequest -> ioa_Request . io_Command    = CMD_WRITE;
  187.                                                             AudioRequest -> ioa_Request . io_Flags        = ADIOF_PERVOL;
  188.                                                             AudioRequest -> ioa_Period            = (GfxBase -> DisplayFlags & PAL ? 3546895 : 3579545) / Rate;
  189.                                                             AudioRequest -> ioa_Volume            = Volume;
  190.                                                             AudioRequest -> ioa_Cycles            = Header . Times;
  191.                                                             AudioRequest -> ioa_Data            = Data;
  192.                                                             AudioRequest -> ioa_Length            = Header . PlayLength;
  193.  
  194.                                                             CopyMem(AudioRequest,AudioControl,sizeof(struct IOAudio));
  195.  
  196.                                                             if(Header . Times)
  197.                                                             {
  198.                                                                 BeginIO((struct IORequest *)AudioRequest);
  199.  
  200.                                                                 for(;;)
  201.                                                                 {
  202.                                                                     SignalSet = Wait(SIG_KILL | SIG_SOUND | SIG_AUDIO);
  203.  
  204.                                                                     if(SignalSet & SIG_KILL)
  205.                                                                     {
  206.                                                                         if(!CheckIO((struct IORequest *)AudioRequest))
  207.                                                                             AbortIO((struct IORequest *)AudioRequest);
  208.  
  209.                                                                         WaitIO((struct IORequest *)AudioRequest);
  210.  
  211.                                                                         CloseDevice((struct IORequest *)AudioRequest);
  212.  
  213.                                                                         DeleteIORequest(AudioRequest);
  214.  
  215.                                                                         DeleteMsgPort(AudioPort);
  216.  
  217.                                                                         FreeVec(Data);
  218.  
  219.                                                                         Terminated = TRUE;
  220.  
  221.                                                                         break;
  222.                                                                     }
  223.  
  224.                                                                     if(SignalSet & SIG_SOUND)
  225.                                                                     {
  226.                                                                         if(!CheckIO((struct IORequest *)AudioRequest))
  227.                                                                             AbortIO((struct IORequest *)AudioRequest);
  228.  
  229.                                                                         WaitIO((struct IORequest *)AudioRequest);
  230.  
  231.                                                                         CloseDevice((struct IORequest *)AudioRequest);
  232.  
  233.                                                                         DeleteIORequest(AudioRequest);
  234.  
  235.                                                                         DeleteMsgPort(AudioPort);
  236.  
  237.                                                                         FreeVec(Data);
  238.  
  239.                                                                         AudioRequest    = NULL;
  240.                                                                         AudioPort    = NULL;
  241.                                                                         Data        = NULL;
  242.  
  243.                                                                         break;
  244.                                                                     }
  245.  
  246.                                                                     if(SignalSet & SIG_AUDIO)
  247.                                                                     {
  248.                                                                         WaitIO((struct IORequest *)AudioRequest);
  249.  
  250.                                                                         CloseDevice((struct IORequest *)AudioRequest);
  251.  
  252.                                                                         DeleteIORequest(AudioRequest);
  253.  
  254.                                                                         DeleteMsgPort(AudioPort);
  255.  
  256.                                                                         FreeVec(Data);
  257.  
  258.                                                                         AudioRequest    = NULL;
  259.                                                                         AudioPort    = NULL;
  260.                                                                         Data        = NULL;
  261.  
  262.                                                                         break;
  263.                                                                     }
  264.                                                                 }
  265.                                                             }
  266.                                                             else
  267.                                                                 BeginIO((struct IORequest *)AudioRequest);
  268.                                                         }
  269.                                                         else
  270.                                                         {
  271.                                                             DeleteIORequest(AudioRequest);
  272.  
  273.                                                             AudioRequest = NULL;
  274.  
  275.                                                             DeleteMsgPort(AudioPort);
  276.  
  277.                                                             AudioPort = NULL;
  278.  
  279.                                                             FreeVec(Data);
  280.  
  281.                                                             Data = NULL;
  282.                                                         }
  283.                                                     }
  284.                                                     else
  285.                                                     {
  286.                                                         DeleteMsgPort(AudioPort);
  287.  
  288.                                                         AudioPort = NULL;
  289.  
  290.                                                         FreeVec(Data);
  291.  
  292.                                                         Data = NULL;
  293.                                                     }
  294.                                                 }
  295.                                                 else
  296.                                                 {
  297.                                                     FreeVec(Data);
  298.  
  299.                                                     Data = NULL;
  300.                                                 }
  301.                                             }
  302.                                             else
  303.                                             {
  304.                                                 FreeVec(Data);
  305.  
  306.                                                 Data = NULL;
  307.                                             }
  308.                                         }
  309.                                     }
  310.  
  311.                                     Close(File);
  312.                                 }
  313.                             }
  314.                         }
  315.  
  316.                         FreeVec(Msg);
  317.  
  318.                         if(Terminated)
  319.                             break;
  320.                     }
  321.                 }
  322.             }
  323.  
  324.             FreeVec(AudioControl);
  325.         }
  326.  
  327.         while(Msg = (struct SoundMessage *)GetMsg(SoundPort))
  328.             FreeVec(Msg);
  329.  
  330.         DeleteMsgPort(SoundPort);
  331.  
  332.         SoundPort = NULL;
  333.     }
  334.  
  335.     Forbid();
  336.  
  337.     Signal((struct Task *)ThisProcess,SIG_HANDSHAKE);
  338.  
  339.     SoundProcess = NULL;
  340. }
  341.  
  342. VOID
  343. SoundCleanup()
  344. {
  345.     if(SoundProcess)
  346.     {
  347.         Signal((struct Task *)SoundProcess,SIG_KILL);
  348.  
  349.         Wait(SIG_HANDSHAKE);
  350.     }
  351. }
  352.  
  353. VOID
  354. PlaySound(int ID,int Volume)
  355. {
  356.     if(!SoundProcess)
  357.     {
  358.         if(SoundProcess = CreateNewProcTags(
  359.             NP_Name,    "Zorkmachine Sound",
  360.             NP_StackSize,    8192,
  361.             NP_Priority,    5,
  362.             NP_WindowPtr,    -1,
  363.             NP_Entry,    SoundServer,
  364.         TAG_DONE))
  365.         {
  366.             Wait(SIG_HANDSHAKE);
  367.         }
  368.     }
  369.  
  370.     if(SoundProcess)
  371.     {
  372.         struct SoundMessage *Msg;
  373.  
  374.         if(Msg = (struct SoundMessage *)AllocVec(sizeof(struct SoundMessage),MEMF_ANY | MEMF_PUBLIC | MEMF_CLEAR))
  375.         {
  376.             Msg -> ID    = ID;
  377.             Msg -> Volume    = Volume;
  378.  
  379.             PutMsg(SoundPort,(struct Message *)Msg);
  380.         }
  381.     }
  382. }
  383.